<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of BUINode
 *
 * @author jianfeng
 */
abstract class BUINode extends BUIBase {

    const TRANSIT_VARIABLE_CURRENTSCREEN = "currentScreen";
    const TRANSIT_VARIABLE_CURRENTSCREENFLOW = "currentScreenFlow";

    //put your code here
    protected $service = null;
    protected $sApp = null;
    protected $operation = null;
    protected $style = null;
    protected $menuManager = null;
    protected $bootStrapMenu = null;
    protected $menu = null;
    public $transitScopeName = 'UINode';
    protected $node = null;
    public $viewPath = null;
    public $formPath = null;
    public $screenPath = null;
    public $screenflowPath = null;
    public $widgetPath = null;
    public $modelPath = null;
    public $uiControlPath = null;
    public $currentScreen = null;
    public $currentScreenFlow = null;
    protected $activeScreen = null;
    protected $activeScreenFlow = null;

    public function __construct($node = NULL) {

        parent::__construct();
        $this->node = $node;

        if (isset($node->uiPath)) {
            $uiPath = $node->uiPath;

            if ($this->modelPath == NULL)
                $this->modelPath = $uiPath . '.models';

            if ($this->screenPath == NULL)
                $this->screenPath = $uiPath . '.screens';

            if ($this->screenflowPath == NULL)
                $this->screenflowPath = $uiPath . '.screenflows';

            if ($this->widgetPath == NULL)
                $this->widgetPath = $uiPath . '.widgets';

            if ($this->uiControlPath == NULL)
                $this->uiControlPath = $uiPath . '.uiControls';

            yii::import($this->modelPath . '.*');
            yii::import($this->screenPath . '.*');
            yii::import($this->widgetPath . '.*');
            yii::import($this->uiControlPath . '.*');
        }

        // $this->resetTransitVariables($this->getId(), $this->transitScopeName);
    }

    public function getNode() {
        return $this->node;
    }

    public function getId() {
        $id = '';

        if ($this->getActiveService() != NULL)
            $id .= $this->service->getId();

        if ($this->getActiveServiceApp() != NULL)
            $id .= '_' . $this->sApp->getId();

        if ($this->getActiveOperation() != NULL)
            $id .= '_' . $this->operation->getId();

        if ($id == "")
            return '000';

        return $id;
    }

    /**
     *
     * @return BService 
     */
    public function getActiveService() {
        if ($this->service == NULL)
            return $this->node->getActiveService();
        return $this->service;
    }

    /**
     *
     * @return BServiceApp 
     */
    public function getActiveServiceApp() {
        if ($this->sApp == NULL)
            return $this->node->getActiveServiceApp();
        return $this->sApp;
    }

    /**
     *
     * @return BOperation 
     */
    public function getActiveOperation() {
        if ($this->operation == NULL)
            return $this->node->getActiveOperation();
        return $this->operation;
    }

    public function setActiveService($service) {
        $this->service = $service;
    }

    public function setActiveServiceApp($app) {
        $this->sApp = $app;
    }

    public function setActiveOperation($opp) {
        $this->operation = $opp;
    }

    public function renderNode($data = NULL) {
        /*
        if (isset($_GET['blyn_scn'])) {
            $screenName = $_GET['blyn_scn'];
            $this->currentScreen = $this->getScreen($screenName);
        }

        //init screenflow if it is an active screenflow
        if (isset($_GET['blyn_sf'])) {
            $sfName = $_GET['blyn_sf'];
            $this->currentScreenFlow = $this->getScreenFlow($sfName);
            $flowIndex = $this->currentScreenFlow->getTransitVariable(BUIScreenFlow::TRANSITVARIABLE_SCREENFLOW_INDEX);
            $flowIndex = is_numeric($flowIndex) ? $flowIndex : 0;
            $this->currentScreenFlow->setIndex($flowIndex);
        }
         * 
         */

        $this->render();

        if ($this->getCurrentScreenFlow() instanceof BUIScreenFlow) {
            $sf = $this->getCurrentScreenFlow();
            $flowIndex = $sf->getTransitVariable(BUIScreenFlow::TRANSITVARIABLE_SCREENFLOW_INDEX);
            if (is_numeric($flowIndex) && $flowIndex > 0)
                $sf->setIndex($flowIndex);
            $this->addRenderView('screeflowLayout', $sf->getLayoutView(), array('uiObj' => $sf));
            $this->getCurrentScreenFlow()->render();
        } elseif ($this->getCurrentScreen() instanceof BUIScreen) {
            $screen = $this->getCurrentScreen();
            $this->addRenderView('ScreenLayout', $screen->getLayoutView(), array('uiObj' => $screen));
            $this->getCurrentScreen()->render();
        }

        $this->getCurrentScreen()->startRender();
        yii::app()->end();
    }

    public function render($data = null) {
        
    }

    //   public abstract function getUrl($data = NULL);

    public function addScreenActionGroup($name, $screenAction) {

        $screenActionStack = $this->getTransitVariable('screenActionStack');

        if ($screenActionStack == NULL) {
            $screenActionStack = array();
        }

        if (!isset($screenActionStack[$name]) || $screenActionStack[$name] == NULL) {
            $screenActionStack[$name] = array();
        }

        array_push($screenActionStack[$name], $screenAction);

        $this->addTransitVariable('screenActionStack', $screenActionStack);
    }

    /**
     *      
     * @param type $data = array('screenflow'=>,'screen'=>,'data'=>)
     */
    /*
      protected function renderNode($data) {
      $service = isset($data['service']) ? $data['service'] : $this->getActiveService();
      $serviceApp = isset($data['serviceApp']) ? $data['serviceApp'] : $this->getActiveServiceApp();
      $operation = isset($data['operation']) ? $data['operation'] : $this->getActiveOperation();
      $screenflow = isset($data['screenflow']) ? $data['screenflow'] : NULL;
      $screen = isset($data['screen']) ? $data['screen'] : NULL;
      $data = isset($data['data']) ? $data['data'] : array();

      if (Blyn::app()->getCurrentNode() instanceof BApplication) {
      $service = FALSE;
      $serviceApp = FALSE;
      $operation = FALSE;
      }

      if (Blyn::app()->getCurrentNode() instanceof BService) {
      $service = FALSE;
      $serviceApp = FALSE;
      $operation = FALSE;
      }

      if (Blyn::app()->getCurrentNode() instanceof BServiceApp) {
      $serviceApp = FALSE;
      $operation = FALSE;
      }

      //$data['uiNode'] = $this;
      //$this->resetTransitVariables($this->getId(), $this->transitScopeName);

      $listLayout = new BUIViewLayout();
      $screen = new $screen;
      $screen->setUINode(Blyn::app()->getCurrentNode()->getUIManager());

      if ($service != FALSE) {
      $servicescreen = new BScreenService();
      $servicescreen->setUINode(Blyn::app()->getActiveService()->getUIManager());
      $listLayout->addViewItem('service', array('screen' => $servicescreen));
      }
      if ($serviceApp != FALSE)
      $listLayout->addViewItem('serviceApp', array('screen' => $screen));
      if ($operation != FALSE)
      $listLayout->addViewItem('operation', array('screen' => $screen));

      $listLayout->addViewItem('viewNode', array('screen' => $screen, 'screenflow' => $screenflow, 'uiNode' => $this, 'data' => $data));

      $controller = yii::app()->getController();
      $controller->render('page', array('uiNode' => $this, 'layout' => $listLayout));
      }
     * 
     */

    public function getScreenActionGroup($name) {
        $screenActionStack = $this->getTransitVariable('screenActionStack');
        return $screenActionStack[$name];
    }

    public function addTransitVariable($name, $value, $scope = NULL, $type = NULL) {

        $tObj = Blyn::app()->getTransitObj();

        //if ($name == BTransitObj::VariableName_Id)
        //return $tObj->addTransitVariable(BTransitObj::Scope_AppMeta, BTransitObj::V_CurrentNodeId, $value);

        return $tObj->addTransitVariable(BTransitObj::Scope_UINode, $name, $value);
    }

    public function getTransitVariable($name, $scope = NULL, $type = NULL) {

        $tObj = Blyn::app()->getTransitObj();
        /*
          $currentNode = $tObj->getTransitVariable(BTransitObj::Scope_Application, BTransitObj::VariableName_CurrentNode);

          if ($name == BTransitObj::VariableName_Id) {
          //return $tObj->getTransitVariable(BTransitObj::Scope_AppMeta, BTransitObj::V_CurrentNodeId);
          $currentNode = $tObj->getTransitVariable($scope, $name);
          }

          if ($name === BTransitObj::V_CurrentScreenId)
          return $tObj->getTransitVariable(BTransitObj::Scope_AppMeta, BTransitObj::V_CurrentScreenId);
          if ($name === BTransitObj::V_CurrentScreenClass)
          return $tObj->getTransitVariable(BTransitObj::Scope_AppMeta, BTransitObj::V_CurrentScreenClass);
          if ($name === BTransitObj::V_CurrentScreenFlowId)
          return $tObj->getTransitVariable(BTransitObj::Scope_AppMeta, BTransitObj::V_CurrentScreenFlowId);
          if ($name === BTransitObj::V_CurrentScreenFlowClass)
          return $tObj->getTransitVariable(BTransitObj::Scope_AppMeta, BTransitObj::V_CurrentScreenFlowClass);
         * 
         */

        return $tObj->getTransitVariable(BTransitObj::Scope_UINode, $name);

        //return FALSE;       
    }

    public function resetTransitVariable($name = NULL) {
        //only when uinode changed, reset transit variables
        $tObj = Blyn::app()->getTransitObj();
        if ($name == NULL) {
            $tId = $this->getTransitVariable(BTransitObj::VariableName_Id);
            $myId = $this->getId();
            if ($tId != $myId) {
                $tObj->resetTransitVariable(BTransitObj::Scope_UINode);
                //$tObj->resetTransitVariable(BTransitObj::Scope_AppMeta);
                $this->addTransitVariable(BTransitObj::VariableName_Id, $myId);
            }
        } else {
            //if (name == BTransitObj::VariableName_Id)
            //return $tObj->resetTransitVariable(BTransitObj::Scope_AppMeta, BTransitObj::V_CurrentNodeId);
            $tObj->resetTransitVariable(BTransitObj::Scope_UINode, $name);
        }
    }

    public function resetNode($data = array()) {
        if (isset($_GET['blyn_scn']))
            unset($_GET['blyn_scn']);
        if (isset($_GET['blyn_sf']))
            unset($_GET['blyn_sf']);
        $this->currentScreen = NULL;
        $this->currentScreenFlow = NULL;
    }

    protected function registerMenu($event) {
        //initialize menus for site from store
        $savedSiteMenu = Blyn::app()->getCurrentUser()->getTransitVariable('SiteMenu');

        if ($savedSiteMenu != NULL)
            yii::app()->getController()->menu = $savedSiteMenu;
        else {
            Blyn::app()->getCurrentUser()->addTransitVariable('SiteMenu', yii::app()->getController()->menu);
        }
    }

    public function getUINodeFilesPath($type = 'viewPath') {

        $viewPath = FALSE;
        $formPath = FALSE;

        $node = Blyn::app()->getCurrentNode();

        if ($node instanceof BOperation || $node instanceof BServiceApp) {
            $viewPath = Blyn::app()->getActiveServiceApp()->getUIManager()->viewPath;
            $formPath = Blyn::app()->getActiveServiceApp()->getUIManager()->formPath;
        }

        if ($viewPath == FALSE) {
            $viewPath = Blyn::app()->getUIManager()->viewPath;
        }

        if ($formPath == FALSE) {
            $formPath = Blyn::app()->getUIManager()->formPath;
        }

        if ($type == 'formPath')
            return $formPath;

        return $viewPath;
    }

    /**
     * 
     * @return BUIScreen
     */
    public function getCurrentScreen() {
        if ($this->currentScreen == NULL) {
            $currentScreen = $this->getTransitVariable(BTransitObj::VariableName_Class);
            if ($currentScreen != NULL)
                $this->currentScreen = $this->getScreen($currentScreen);
        }

        if ($this->currentScreenFlow instanceof BUIScreenFlow)
            $this->currentScreen = $this->currentScreenFlow->current();

        if ($this->currentScreen == NULL && isset($this->startScreen) && $this->startScreen != NULL)
            $this->currentScreen = $this->getScreen($this->startScreen);

        /*
          if ($this->getCurrentScreenFlow() != NULL) {
          $this->currentScreen = $this->getCurrentScreenFlow()->current();
          }
         * 
         */

        return $this->currentScreen;
    }

    public function getCurrentScreenFlow() {
        /**
         * if currentScreenFlow is null, can init it by checking transit variable
         * maybe this screenflow has been continued by last same screenflow 
         */
        if ($this->currentScreenFlow == NULL) {
            $flow = $this->getTransitVariable(BTransitObj::VariableName_Class);
            if ($flow == NULL)
                $flow = $this->startScreenFlow == NULL ? NULL : $this->startScreenFlow;
            if ($flow != NULL) {
                //$this->currentScreenFlow = is_array($flow) ? key($flow) : $flow;
                $this->currentScreenFlow = $flow;
                if (is_string($this->currentScreenFlow)) {
                    $this->currentScreenFlow = $this->getScreenFlow($this->currentScreenFlow);
                }

                if ($this->currentScreenFlow instanceof BUIScreenFlow) {
                    $flowIndex = $this->getTransitVariable(BUIScreenFlow::TRANSITVARIABLE_SCREENFLOW_INDEX);
                    //$flowIndex = $flow[BUIScreenFlow::TRANSITVARIABLE_SCREENFLOW_INDEX];
                    $flowIndex = is_numeric($flowIndex) ? $flowIndex : 0;
                    $this->currentScreenFlow->setIndex($flowIndex);
                }
            }
        }

        return $this->currentScreenFlow;
    }

    public function setCurrentScreenFlow($screenFlow) {
        $this->currentScreenFlow = $screenFlow;

        /**
         * reset screenflow means if currentscreen flow changed, should empty variables for currentscreenflow
         * and ready for new variables of new current screenflow 
         */
        if ($screenFlow instanceof BUIScreenFlow) {
            $screenFlow->resetTransitVariable();
        }
    }

    public function setCurrentScreen($screen) {
        $this->currentScreen = $screen;

        //if currentScreen is not member of screenflow, means not active screenflow
        if ($screen instanceof BUIScreen && !$screen->isMemberOfScreenFlow())
            $this->setCurrentScreenFlow(FALSE);
        //$screen->resetTransitVariables();
    }

    public function getScreen($name) {

        //if screen is currentscreen, return it
        if ($this->currentScreen instanceof BUIScreen) {
            if ($this->currentScreen->getName() == $name)
                return $this->currentScreen;
        }

        $screen = new $name;
        $screen->setUINode($this);

        return $screen;
    }

    public function getScreenFlow($name) {

        //if screen is currentscreen, return it
        if ($this->currentScreenFlow instanceof BUIScreenFlow) {
            if ($this->currentScreenFlow->getName() == $name)
                return $this->currentScreenFlow;
        }

        $scnFlow = new BUIScreenFlow($name);
        $scnFlow->setUINode($this);

        return $scnFlow;
    }

   

    /*
      public function onBeforeRenderNode($event) {
      $this->raiseEvent('onBeforeRenderNode', $event);
      }


      protected function resetUINodeOnSwitchUINode($event) {
      $uiNode = $event->sender;

      $this->resetTransitVariables($uiNode->getId(), $uiNode->transitScopeName);
      }
     * 
     */
}

?>
